package bme.andraskindler.treenventory.fragment;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import android.widget.ViewFlipper;
import bme.andraskindler.treenventory.R;
import bme.andraskindler.treenventory.activity.OptionsActivity;
import bme.andraskindler.treenventory.imagemanipulation.ImageProcessor;
import bme.andraskindler.treenventory.widget.CameraSurfaceView;


/**
 * 
 * @author andraskindler
 *
 *A kalibrációt megvalósító fragment, szülője a CalibrateActivity. Négy felületet tartalmaz, melyeken egy ViewFlipperen keresztül, varázslós módon lehet végigmenni.
 */
public class CalibrateFragment extends Fragment {

	private static final int CAMERA_ID = 0;
	private ImageView mPreview;
	private TextView mCalibrationInfo;
	private Bitmap mBitmap;
	private ProgressDialogFragment mProgressDialog;

	public CalibrateFragment() {
		super();
	}

	public static CalibrateFragment newInstance() {
		return new CalibrateFragment();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		final ViewFlipper viewflipper = (ViewFlipper) inflater.inflate(R.layout.fragment_calibrate, container, false);

		final Animation slideInRight = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_in_right);
		final Animation slideOutLeft = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_out_left);

		viewflipper.setInAnimation(slideInRight);
		viewflipper.setOutAnimation(slideOutLeft);

		final RelativeLayout page1 = (RelativeLayout) viewflipper.findViewById(R.id.fragment_calibrate_camera);
		final float scale = getResources().getDisplayMetrics().density;
		final float width = getResources().getDisplayMetrics().widthPixels;
		final float height = getResources().getDisplayMetrics().heightPixels - 40 * scale;
		final LayoutParams lp = new LayoutParams((int) width, (int) height);
		lp.setMargins((int) (5 * scale), (int) (5 * scale), (int) (5 * scale), (int) (5 * scale));
		lp.addRule(RelativeLayout.ABOVE, R.id.fragment_calibrate_1_text);
		final CameraSurfaceView camera = new CameraSurfaceView(getActivity());
		camera.setId(CAMERA_ID);
		camera.setLayoutParams(lp);
		page1.addView(camera);

		final View.OnClickListener clicklistener = new OnClickListener() {

			public void onClick(View v) {
				switch (v.getId()) {
				case R.id.fragment_calibrate_page0_next:
					viewflipper.setDisplayedChild(1);
					break;
				case CAMERA_ID:
					viewflipper.setDisplayedChild(2);
					final SharedPreferences preferences = getActivity().getSharedPreferences(OptionsActivity.SETTINGS, Context.MODE_PRIVATE);
					camera.shoot(false, preferences.getInt(OptionsActivity.SETTINGS_RESOLUTION, 1), CameraSurfaceView.PICTURE_PREVIEW);
					break;
				case R.id.fragment_calibrate_page2_back:
					viewflipper.setDisplayedChild(1);
					break;
				case R.id.fragment_calibrate_page2_next:
					viewflipper.setDisplayedChild(3);
					new calibrationTask().execute();
					break;
				case R.id.fragment_calibrate_page3_finish:
					getActivity().finish();
					break;
				default:
					break;
				}

			}
		};

		Button.class.cast(viewflipper.findViewById(R.id.fragment_calibrate_page0_next)).setOnClickListener(clicklistener);
		camera.setOnClickListener(clicklistener);
		Button.class.cast(viewflipper.findViewById(R.id.fragment_calibrate_page2_back)).setOnClickListener(clicklistener);
		Button.class.cast(viewflipper.findViewById(R.id.fragment_calibrate_page2_next)).setOnClickListener(clicklistener);
		Button.class.cast(viewflipper.findViewById(R.id.fragment_calibrate_page3_finish)).setOnClickListener(clicklistener);
		mCalibrationInfo = TextView.class.cast(viewflipper.findViewById(R.id.fragment_calibrate_finished_text));

		mPreview = (ImageView) viewflipper.findViewById(R.id.fragment_calibrate_image);

		return viewflipper;
	}

	public void setPhoto(Bitmap bitmap) {
		mBitmap = bitmap;
		mPreview.setImageBitmap(bitmap);
	}

	private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(getActivity()) {
		@Override
		public void onManagerConnected(int status) {
			switch (status) {
			case LoaderCallbackInterface.SUCCESS: {
			}
				break;
			default: {
				super.onManagerConnected(status);
			}
				break;
			}
		}
	};

	@Override
	public void onResume() {
		super.onResume();
		OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, getActivity(), mLoaderCallback);
	}

	/**
	 * 
	 * @author andraskindler
	 *
	 *Ez a belső osztály egy külső szálon elindítja a kamerakalibrálást.
	 */
	protected class calibrationTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			ImageProcessor.findCorrectionMatrix(mBitmap);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			mCalibrationInfo.setText("Sikeres kalibrálás!\n\n");
			mProgressDialog.dismiss();
		}

		@Override
		protected void onPreExecute() {
			mProgressDialog = ProgressDialogFragment.newInstance("Kérem, várjon", "Kameraparaméterek megállapítása folyamatban...");
			mProgressDialog.show(getFragmentManager(), "progress-dialog-fragment");
		}

	}
}
